﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using UpdateServers.Models;
using System.Windows.Forms;

namespace UpdateServers.Command
{
    /// <summary>
    /// Socket服务端
    /// </summary>
    public class SocketServers
    {
        /// <summary>
        /// 服务监听IP地址
        /// </summary>
        private IPEndPoint IPAddr { get; set; }
        /// <summary>
        /// 文件地址
        /// </summary>
        public string FilePath { get; set; }
        /// <summary>
        /// 服务
        /// </summary>
        private Socket socketServer { get; set; }
        /// <summary>
        /// 是否要启动
        /// </summary>
        private bool IsStart = true;

        public DataGridView dataGridView { get; set; }
        /// <summary>
        /// 连接客户端服务
        /// </summary>
        public Dictionary<string, Socket> ClistAccepts = new Dictionary<string, Socket>();
        /// <summary>
        /// 数据列表
        /// </summary>
        private static List<ServerModel> datalist = new List<ServerModel>();

        private static object clocket=new object();
        /// <summary>
        /// 构造Socket连接
        /// </summary>      
        /// <param name="port">端口</param>
        public SocketServers(int port)
        {
            try
            {
                this.IPAddr = new IPEndPoint(IPAddress.Any, port);
                this.socketServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            }
            catch (Exception)
            {
                throw;
            }

        }
        /// <summary>
        /// 启动服务
        /// </summary>
        public void Start()
        {

            try
            {
                IsStart = true;
                this.socketServer.Bind(new IPEndPoint(IPAddress.Any, this.IPAddr.Port));
                this.socketServer.Listen(100);
                while (IsStart)
                {
                    var clieter = this.socketServer.Accept();
                    var ip = ((IPEndPoint)clieter.RemoteEndPoint).Address.ToString();


                    if (ClistAccepts.ContainsKey(ip))
                    {
                        ClistAccepts[ip] = clieter;
                    }
                    else
                    {
                        ClistAccepts.Add(ip, clieter);
                    }
                    //获取客户端消息
                    GetMessage(clieter);
                }


            }
            catch (Exception ex)
            {
                Loger.Log(ex.ToJsonString(), "Error");

            }

        }

        /// <summary>
        /// 停止服务
        /// </summary>
        public bool Stop()
        {
            var result = false;
            try
            {
                if (ClistAccepts.Count() > 0)
                {
                    foreach (var item in ClistAccepts.Values)
                    {
                        item.Disconnect(false);
                        item?.Close();
                        item?.Dispose();
                    }
                    ClistAccepts.Clear();
                }
                IsStart = false;
                this.socketServer?.Close();

                result = true;
            }
            catch (Exception ex)
            {
                result = false;

                Loger.Log(ex.ToJsonString(), "Error");
            }

            return result;
        }

        /// <summary>
        /// 文件发送
        /// </summary>
        public void SendFile(Socket socket, string fileroot)
        {
            if (socket != null && socket.Connected)
            {
                socket.SendFile(fileroot);
            }

        }
        /// <summary>
        /// 数据发送类
        /// </summary>
        /// <param name="socket"></param>
        /// <param name="buffer"></param>
        /// <param name="outtime"></param>
        /// <returns></returns>
        private int SendData(Socket socket, byte[] buffer, int outtime)
        {
            if (socket == null || socket.Connected == false)
            {
                throw new ArgumentException("参数socket 为null，或者未连接到远程计算机");
            }
            if (buffer == null || buffer.Length == 0)
            {
                throw new ArgumentException("参数buffer 为null ,或者长度为 0");
            }
            int result = 0;
            try
            {
                int left = buffer.Length;
                int sndLen = 0;
                while (true)
                {
                    if ((socket.Poll(outtime * 100, SelectMode.SelectWrite) == true))
                    {
                        sndLen = socket.Send(buffer, sndLen, left, SocketFlags.None);
                        left -= sndLen;
                        if (left == 0)
                        {
                            //数据发送完成
                            result = 0;
                            break;
                        }
                        else
                        {
                            if (sndLen > 0)
                            {
                                continue;
                            }
                            else
                            {
                                //数据异常
                                result = -1;
                                break;
                            }
                        }
                    }
                }
            }
            catch (Exception)
            {
                result = -2;
                throw;
            }
            return result;
        }
        /// <summary>
        /// 连接测式
        /// </summary>
        /// <param name="byts"></param>
        /// <returns></returns>
        public void SendTo(byte[] byts)
        {
            if (ClistAccepts.Count() > 0)
            {
                foreach (var item in ClistAccepts)
                {
                    if (item.Value.Connected)
                    {
                        try
                        {
                            item.Value.Send(byts);
                        }
                        catch (Exception)
                        {
                            ClistAccepts.Remove(item.Key);
                        }

                    }
                    else
                    {
                        ClistAccepts.Remove(item.Key);
                    }
                }
            }

        }

        /// <summary>
        /// 发送消息
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        public bool SendMessage(Socket _clienter, String text)
        {
            bool result = false;
            if (_clienter != null)
            {
                byte[] sendbyte = Encoding.UTF8.GetBytes(text);
                var index = _clienter.Send(sendbyte, sendbyte.Length, SocketFlags.None);
                result = index > 0;
            }
            return result;
        }
        /// <summary>
        /// 设置数据
        /// </summary>
        /// <param name="sm"></param>
        public void SetData(ServerModel sm)
        {
            lock (clocket)
            {
                if (sm != null)
                {
                    if (datalist.Where(w => w.ClientIp == sm.ClientIp).Any())
                    {
                        datalist.ForEach(w =>
                        {
                            if (w.ClientIp == sm.ClientIp)
                            {
                                w.UpdateState = sm.UpdateState;
                                w.UpdateTime = sm.UpdateTime;
                            }

                        });

                    }
                }
            }
           

        }
        /// <summary>
        /// 获取数据列表
        /// </summary>
        /// <returns></returns>
        public List<ServerModel> GetGridData()
        {
            lock (clocket)
            {
                if (this.ClistAccepts.Count > 0)
                {
                    foreach (var item in this.ClistAccepts)
                    {
                        if (datalist.Where(w => w.ClientIp == item.Key).Any())
                        {
                            datalist.ForEach((w) =>
                            {
                                if (w.ClientIp == item.Key)
                                {
                                    w.ConnectionState = item.Value.Connected ? "已连接" : "已断开";
                                }

                            });
                        }
                        else
                        {
                            datalist.Add(new ServerModel()
                            {
                                ClientIp = item.Key,
                                ConnectionState = item.Value.Connected ? "已连接" : "已断开",

                            });
                        }
                    }
                    //同步数据
                    foreach (var item in datalist)
                    {
                        if (ClistAccepts.Count > 0)
                        {
                            if (!ClistAccepts.ContainsKey(item.ClientIp))
                            {
                                datalist.Remove(item);
                            }
                        }
                    }
                }
                else
                {
                    datalist.Clear();
                }

            }
          

            return datalist;
        }


        /// <summary>
        /// 获取消息
        /// </summary>
        /// <returns></returns>
        public void GetMessage(Socket socket)
        {
            Task.Run(() =>
            {
                while (true)
                {
                    try
                    {
                        if (socket.Connected)
                        {
                            byte[] recbyte = new byte[1024];
                            int bytes = socket.Receive(recbyte, recbyte.Length, SocketFlags.None);
                            if (bytes > 1)
                            {
                                var result = Encoding.UTF8.GetString(recbyte, 0, bytes);
                                var json = result.JsonToObject<ServerModel>();
                                if (json != null)
                                {
                                    this.SetData(json);

                                }
                            }


                        }
                        else
                        {
                            break;
                        }
                    }
                    catch (Exception)
                    {

                    }

                }
            });



        }

        /// <summary>
        /// 关闭连接
        /// </summary>
        public void Close()
        {
            if (ClistAccepts.Count() > 0)
            {
                foreach (var item in ClistAccepts.Values)
                {
                    item.Close();
                    item.Dispose();
                }

            }
            this.socketServer.Close();
            this.socketServer.Dispose();


        }
    }
}
